﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using System.Text;
using System.Transactions;
using System.Web;
using System.Web.Mvc;
using Microsoft.Web.Helpers;
using MusicHouse.Models;
using MusicHouse.Models.Views;
using MusicHouse.Util;

namespace MusicHouse.Controllers
{
    public class PartiturasController : Controller
    {
        private readonly casamusicaEntities1 _db = new casamusicaEntities1();

        #region PaginaAtual

        public int PaginaAtual
        {
            get { return int.Parse(Request.QueryString["PaginaAtual"] ?? "1"); }
        }

        #endregion
        
        #region Index

        public ActionResult Index()
        {
            return View();
        }

        #endregion

        #region ContratarServico

        public ActionResult ContratarServico()
        {
            Usuario usu = AccountManager.RetornarUsuarioCookie() ?? Session["usuario"] as Usuario;
            string parametro = Criptografia.Criptografar("ContratarServico,Partituras", Criptografia.CryptoKey);
            if (usu == null)
            {
                return RedirectToAction("Index", "Account", new { returnUrl = parametro });
            }
            
            return View();
        }

        [HttpPost]
        public ActionResult ContratarServico(Arquivo arquivo)
        {
            #region Verifica usuario logado

            Usuario usu = AccountManager.RetornarUsuarioCookie() ?? Session["usuario"] as Usuario;
            string parametro = Criptografia.Criptografar("ContratarServico,Partituras", Criptografia.CryptoKey);
            if (usu == null)
            {
                return RedirectToAction("Index", "Account", new { returnUrl = parametro });
            }

            #endregion


            #region Validações
#if !DEBUG
            if (!ReCaptcha.Validate(ConfigurationManager.AppSettings["ReCaptcha.PrivateKey"]))
            {
                ModelState.AddModelError("", "Código de segurança (ReCaptcha) Não confere.");
            }
#endif
            if (string.IsNullOrWhiteSpace(arquivo.Descricao))
            {
                ModelState.AddModelError("Descricao", "Nome da música é obrigatória.");
            }
            #endregion

            foreach (string fileName in Request.Files)
            {
                HttpPostedFileBase postedFile = Request.Files[fileName];
                if (postedFile != null && postedFile.ContentLength > 0)
                {
                    double fileinMb = (double)postedFile.ContentLength / (1024 * 1024);
                    double maxSize = 9.216;
                    if (fileinMb > maxSize)
                    {
                        ModelState.AddModelError("", string.Format("Tamanho do Arquivo não pode superar {0}Mb.", maxSize));
                    }
                    else
                    {
                        if (ModelState.IsValid)
                        {
                            using (var tScope = new TransactionScope(TransactionScopeOption.Required))
                            {
                                //postedFile.SaveAs(Server.MapPath("~/Uploads/") + Path.GetFileName(postedFile.FileName));
                                var ms = new MemoryStream();
                                postedFile.InputStream.CopyTo(ms);
                                byte[] array = ms.GetBuffer();

                                arquivo.Conteudo = array;
                                arquivo.Tamanho = postedFile.ContentLength;
                                arquivo.Nome = postedFile.FileName;
                                arquivo.IdUsuario = usu.IdUsuario;
                                _db.arquivo.AddObject(arquivo);
                                _db.SaveChanges();

                                var atend = new Atendimento
                                                        {
                                                            IdArquivo = arquivo.IdArquivo,
                                                            IdUsuario = arquivo.IdUsuario,
                                                            Status = Atendimento.ListaStatus.Aberto.GetHashCode(),
                                                            DataAlteracao = DateTime.Now,
                                                            Descricao = ""
                                                        };
                                _db.atendimento.AddObject(atend);
                                _db.SaveChanges();

                                var currentControllerName = (string)RouteData.Values["controller"];

                                #region Enviar Email

                                string remetenteEmail = ConfigurationManager.AppSettings["RemetenteEmail"]; //O e-mail do remetente
                                string passwordEmail = ConfigurationManager.AppSettings["PasswordEmail"];
                                SmtpClient client = new SmtpClient();
                                client.Credentials = new NetworkCredential(remetenteEmail, passwordEmail);
                                client.EnableSsl = false;  //Adicionando as credenciais do seu e-mail e senha:

                                var mail = new MailMessage
                                               {
                                                   From = new MailAddress(remetenteEmail, "Casa Música", Encoding.UTF8),
                                                   Subject = string.Format("Contratação de serviço de {0}", usu.Nome),
                                                   SubjectEncoding = Encoding.UTF8,
                                                   Body = string.Format(@"
Sr(a). {0}, <br /><br />
Obrigado por Contratar os serviços do <a href='www.casamusica.com.br'>Casa Música</a><br /><br />
Dados da música: <br /><br />
Nome: {1} <br />
Arquivo: {2} <br /><br />
Se tiver alguma dúvida consulte seus pedidos em:
http://www.casamusica.com.br/{3}/ <br /><br />

Cordialmente,<br /><br />
Casa Música
", usu.Nome, arquivo.Descricao, arquivo.Nome, currentControllerName),
                                                   BodyEncoding = Encoding.UTF8,
                                                   IsBodyHtml = true,
                                                   Priority = MailPriority.Normal
                                               };

                                mail.To.Add(usu.LoginEmail);
                                //mail.Bcc.Add(remetenteEmail);

                                try
                                {
                                    client.Send(mail);
                                }
                                catch
                                {
                                    //  so reporta erro se nao for debug para funcionar no ambiente de desenvolvimento
#if !DEBUG
                        throw;
#endif
                                    Console.WriteLine(mail.Body);
                                }

                                #endregion

                                tScope.Complete();
                                string qParametro = Criptografia.Criptografar(arquivo.IdArquivo.ToString(), Criptografia.CryptoKey);
                                return RedirectToAction("FinalizarContratarServico", new { qString=qParametro} );

                            }
                        }
                    }
                }
                else
                {
                    ModelState.AddModelError("Conteudo", "Arquivo é obrigatório.");
                }
            }

            return View(arquivo);
        }

        #endregion

        #region FinalizarContratarServico
        public ActionResult FinalizarContratarServico(string qString)
        {
            if (string.IsNullOrWhiteSpace(qString))
            {
                throw new ArgumentNullException("qString");
            }

            int idArquivo = int.Parse(Criptografia.Descriptografar(qString, Criptografia.CryptoKey));

            Arquivo arquivo = _db.arquivo.FirstOrDefault(a => a.IdArquivo == idArquivo);
            if (arquivo==null)
            {
                ViewBag.Mensagem = "Arquivo não encontrado";
            }

            //return Download(qString);
            ViewBag.qString = Criptografia.Criptografar(arquivo.IdArquivo.ToString(), Criptografia.CryptoKey);
            return View(arquivo);
        }

        #endregion

        #region Download

        public ActionResult Download(string qString)
        {
            if (string.IsNullOrWhiteSpace(qString))
            {
                throw new ArgumentNullException("qString");
            }

            int idArquivo = int.Parse(Criptografia.Descriptografar(qString, Criptografia.CryptoKey));
            Arquivo arquivo = _db.arquivo.FirstOrDefault(a => a.IdArquivo == idArquivo);
            if (arquivo == null)
            {
                ViewBag.Mensagem = "Arquivo não encontrado";
            }
            else
            {
                var cd = new ContentDisposition
                             {
                                 // for example foo.bak
                                 FileName = arquivo.Nome,

                                 // always prompt the user for downloading, set to true if you want 
                                 // the browser to try to show the file inline
                                 Inline = false,
                             };
                Response.AppendHeader("Content-Disposition", cd.ToString());
                return File(arquivo.Conteudo, "application/octet-stream");
            }
            return View();
        }

        #endregion

        #region MeusPedidos

        public ActionResult MeusPedidos(string qString)
        {
            ViewBag.MensagemConfirmacao = !string.IsNullOrWhiteSpace(qString) ? Criptografia.Descriptografar(qString, Criptografia.CryptoKey) : string.Empty;

            var currentControllerName = (string)RouteData.Values["controller"];
            var currentActionName = (string)RouteData.Values["action"];

            Usuario usu = AccountManager.RetornarUsuarioCookie() ?? Session["usuario"] as Usuario;
            string parametro = Criptografia.Criptografar(string.Format("{0},{1}", currentActionName, currentControllerName), Criptografia.CryptoKey);
            if (usu == null)
            {
                return RedirectToAction("Index", "Account", new {returnUrl = parametro});
            }

            var lista = _db.arquivo.Where(a => a.IdUsuario == usu.IdUsuario);
            int totalReg = lista.Count();
            lista = lista.Pagina(PaginaAtual, Funcoes.TamanhoPagina, p => p.Descricao, true);
            
            ViewBag.Paginas = Funcoes.RetornarListaPaginacao(totalReg, currentActionName, currentControllerName, PaginaAtual);
            return View(lista);
        }

        #endregion

        #region Delete

        public ActionResult Delete(int id)
        {
            Usuario usu = AccountManager.RetornarUsuarioCookie() ?? Session["usuario"] as Usuario;
            string parametro = Criptografia.Criptografar(string.Format("{0},{1}", "MeusPedidos", "Partituras"),
                                                         Criptografia.CryptoKey);
            if (usu == null)
            {
                return RedirectToAction("Index", "Account", new {returnUrl = parametro});
            }

            using (var tScope = new TransactionScope(TransactionScopeOption.Required))
            {
                Arquivo arq = _db.arquivo.FirstOrDefault(a => a.IdArquivo == id && a.IdUsuario == usu.IdUsuario);
                if (arq != null)
                {
                    string nomeArquivo = arq.Nome;
                    var listaAtend = _db.atendimento.Where(a => a.IdArquivo == arq.IdArquivo);
                    foreach(var atend in listaAtend)
                    {
                        _db.atendimento.DeleteObject(atend);
                    }
                    _db.arquivo.DeleteObject(arq);
                    _db.SaveChanges();
                    tScope.Complete();

                    string qParametro =
                        Criptografia.Criptografar(string.Format("Arquivo: {0}, excluído com sucesso.", nomeArquivo),
                                                  Criptografia.CryptoKey);
                    return RedirectToAction("MeusPedidos", new {qString = qParametro});
                }
            }

            return RedirectToAction("MeusPedidos");
        }

        #endregion

        #region Details

        public ActionResult Details(int id)
        {
            var currentControllerName = (string) RouteData.Values["controller"];
            var currentActionName = (string) RouteData.Values["action"];

            Usuario usu = AccountManager.RetornarUsuarioCookie() ?? Session["usuario"] as Usuario;
            string parametro =
                Criptografia.Criptografar(string.Format("{0},{1}", currentActionName, currentControllerName),
                                          Criptografia.CryptoKey);
            if (usu == null)
            {
                return RedirectToAction("Index", "Account", new {returnUrl = parametro});
            }

            var arquivo = _db.arquivo.FirstOrDefault(a => a.IdArquivo == id);

            return View(arquivo);
        }

        #endregion

        public static string EscreveStatusAtendimento(long idArquivo)
        {
            var _db = new casamusicaEntities1();
            var lista = _db.atendimento.Where(a => a.IdArquivo == idArquivo).ToList();
            int idMax;
            string status = string.Empty;
            if (lista.Count>0)
            {
                idMax = lista.Max(b => b.idAtendimento);
                var anda = lista.FirstOrDefault(a => a.idAtendimento == idMax);
                if (anda != null && anda.Status != null) status = ((Atendimento.ListaStatus) anda.Status).ToString();
            }
            
            return status;
        }

    }
}
